<?php
/**
 * Author:xsc
 * Time:2023/8/31 11:15
 */

namespace App\Service\Common;

use App\Common\Tools;
use App\Extensions\Common\OssService;
use App\Params\Common\MerchantsInfoCreateParams;
use App\Repository\AssortRepo;
use App\Repository\MerchantsInfoApplyForRepo;
use App\Repository\OpenPlatformRepo;
use App\Repository\SpecialOrderRepo;
use App\Repository\SpecialPrivilegeRepo;
use App\Service\BaseService;
use App\Common\ResponseCode;
use App\Exceptions\BusinessException;
use App\Params\Common\MerchantsParams;
use App\Repository\ConfigRepo;
use App\Repository\MerchantsInfoRepo;
use App\Repository\SpecialRepo;
use App\Extensions\Common\RedisService;
use App\Common\Constant;
use Illuminate\Support\Facades\Cache;
use App\Params\Common\MerchantsInfoSaveParams;
use Illuminate\Support\Facades\Log;

class MerchantsService extends BaseService
{

    /**
     * 查询创作者信息(带缓存)
     * @param string $access_mid
     * @return array|mixed
     * @throws \RedisException
     * Author:xsc
     * Time:2023/10/16 16:22
     */
    public function getInfoWithCache(string $access_mid)
    {
        $redis = RedisService::getInstance();
        $key = Constant::MERCHANTS_INFO . $access_mid;
        $cache = $redis->get($key);
        if ($cache) {
            return json_decode($cache, true);
        }

        // 接入商户信息
        $info = MerchantsInfoRepo::getInstance()->getInfoByAccessMid($access_mid);

        if ($info) {
            $redis->set($key, json_encode($info, 256), 3600);
        }
        return $info;
    }

    /**
     * 查询创作者信息
     * @param MerchantsParams $params
     * @return array
     * @throws BusinessException
     * Author:xsc
     * Time:2023/9/4 19:13
     */
    public function getInfo(MerchantsParams $params)
    {
        $access_mid = $params->getMid();

        // 接入商户信息
        $info = MerchantsInfoRepo::getInstance()->getInfoByAccessMid($access_mid);
        if (!$info) {
            throw new BusinessException(ResponseCode::MERCHANTS_NOT_FUND);
        }

        // 铸造单价
        $casting_price = ConfigRepo::getInstance()->getConfigValue('casting_price');

        // 根据应用环境拟定默认值
        if (env('APP_ENV') != 'pro')
        {
            $assort_link = 'https://sandnft.sand.com.cn/merchant/';
        }else{
            $assort_link = 'https://www.sandnft.com.cn/merchant/';
        }
        $assort_link_domain = env('MERCHANT_DOMAIN',$assort_link);

        $link = $assort_link_domain.$info['assort_link'].'/';

        // 获取统计信息
        $statistics = SpecialOrderRepo::getInstance()->getByMerIdStatisticsInfo($info['mer_id']);
        $data = [
            'base_info'=>$info,
            'assort_link'=>$link,
            'order_statistics'=>[
                // 今日订单成交数量
                'today_order_number'=>$statistics['today_order_number'],
                // 累计订单成交数量
                'total_order_number'=>$statistics['total_order_number'],
                // 今日订单成交金额
                'today_order_money'=>$statistics['today_order_money'],
                // 累计订单成交金额
                'total_order_money'=>$statistics['total_order_money'],
            ],
            'user_name'     => $info['user_name'],
            'remaining'     => $info['remaining'],
            'casting_price' => $casting_price,
        ];

        return $data;
    }

    /**
     * 查询创作者全部藏品
     * @param MerchantsParams $params
     * @return array
     * @throws BusinessException
     * Author:xsc
     * Time:2023/9/4 19:14
     */
    public function getSpecialList(MerchantsParams $params)
    {
        $access_mid = $params->getMid();
        $page = $params->getPage() ?: 1;
        $page_size = $params->getPageSize() ?: 20;

        $page_size = $page_size > 100 ? 100 : $page_size;

        // 接入商户信息
        $info = MerchantsInfoRepo::getInstance()->getInfoByAccessMid($access_mid);
        if (!$info) {
            throw new BusinessException(ResponseCode::MERCHANTS_NOT_FUND);
        }

        // 创作者全部藏品数量
        $total = SpecialRepo::getInstance()->getCountByAccessMid($access_mid);

        // 创作者全部藏品
        $list = SpecialRepo::getInstance()->getListByAccessMid($access_mid, $page, $page_size);
        foreach ($list as &$item) {
            $item['privilege_status'] = SpecialPrivilegeRepo::getInstance()->specialIsExistPrivilege($item['special_id']);
            $item['rest_cnt'] = $item['all_count'] - $item['sale_count'];
        }
        $data = [
            'total' => $total,
            'list'  => $list,
        ];

        return $data;
    }

    /**
     * 创作者入驻
     * @param MerchantsInfoCreateParams $param
     * @return string
     * @throws BusinessException
     * @throws \OSS\Core\OssException
     * @author shen.zk
     * @date 2023-10-23 17:55
     */
    public function merchantInfoCreateService(MerchantsInfoCreateParams $param)
    {
        $params = $param->toArray();
        $this->baseCheckMerchantInfoParams($params);

        // 验证接入商户号 申请商户号
        $checkApplyForMid = MerchantsInfoApplyForRepo::getInstance()->getByApplyForMid($params['apply_for_mid']);
        if (!empty($checkApplyForMid) && $checkApplyForMid->status != 2)
            throw new BusinessException(ResponseCode::PARAM_ILLEGAL,['error'=>'接入商户号已存在']);
        // 已有商户号
        $flag = MerchantsInfoRepo::getInstance()->getInfoByAccessMid($params['apply_for_mid']);
        if (!empty($flag))
            throw new BusinessException(ResponseCode::PARAM_ILLEGAL,['error'=>'接入商户号已存在']);

        // 验证分账及分账比例
        $params['is_multipart'] = 0;
        if (!empty($param->getAccsplitMerNo()) && !empty($param->getMultipartRate()))
        {
            // 验证分账比例是否大于70%
            if ($params['multipart_rate'] > '0.7')
                throw new BusinessException(ResponseCode::PARAM_ILLEGAL,['error'=>'分账比例不得大于70%']);

            $params['is_multipart'] = 1;
            $params['account_no'] = $param->getAccsplitMerNo();
            unset($params['accsplit_mer_no']);
        }else{
            unset($params['accsplit_mer_no']);
            unset($params['multipart_rate']);
        }

        // 获取归属平台ID
        $cacheInfo = Cache::get(Constant::MERCHANTID.':'.$params['access_mid']);
        if (empty($cacheInfo))
        {
            $merchantsInfo = OpenPlatformRepo::getInstance()->getByPlatformNo($params['access_mid']);
            if (empty($merchantsInfo))
                throw new BusinessException(ResponseCode::PARAM_ILLEGAL,['error'=>'平台商户不存在']);

            // 反向写入cache
            Cache::put(Constant::MERCHANTID.':'.$params['access_mid'],json_encode($merchantsInfo));
            $cacheInfo = Cache::get(Constant::MERCHANTID.':'.$params['access_mid']);
        }

        $cacheMerchants = json_decode($cacheInfo,true);


        $params['apply_for_num'] = Tools::build_hash_no();
        $params['end_time'] = strtotime('+ 10 year');
        $params['platform_id'] = $cacheMerchants['id'];
        unset($params['access_mid']);
        $params['create_time'] = date('Y-m-d H:i:s');
        $params['update_time'] = date('Y-m-d H:i:s');

        // 上传头像
        $params['portrait'] = OssService::getInstance()->saveFile($params['portrait']);
        $result = MerchantsInfoApplyForRepo::getInstance()->save($params);
        if (!$result)
            throw new BusinessException(ResponseCode::PARAM_ILLEGAL,['error'=>'入驻申请失败']);

        // 返回申请编号
        return $params['apply_for_num'];

    }

    /**
     * 创作者入驻&编辑 参数校验
     * @param array $params
     * @throws BusinessException
     * @author shen.zk
     * @date 2023-10-24 17:54
     */
    protected function baseCheckMerchantInfoParams(array $params)
    {
        $user_name = $params['user_name'];
        // 验证名称是否长度
        if (mb_strlen($user_name) > 4)
            throw new BusinessException(ResponseCode::PARAM_ILLEGAL,['error'=>'创作者名称长度错误']);

        // 验证手机号格式
        if (!Tools::verifyMobileFormat($params['contact_phone']))
            throw new BusinessException(ResponseCode::PARAM_ILLEGAL,['error'=>'手机号格式错误']);

        // 验证联系人手机号是否唯一
        $phone = MerchantsInfoRepo::getInstance()->getPhone($params['contact_phone']);
        if (!empty($phone))
            throw new BusinessException(ResponseCode::PARAM_ILLEGAL,['error'=>'联系人手机号已存在']);

        // 验证手机号是否已存在
        $checkPhone = MerchantsInfoApplyForRepo::getInstance()->getByPhone($params['contact_phone']);
        if (!empty($checkPhone) && $checkPhone->status == 1)
            throw new BusinessException(ResponseCode::PARAM_ILLEGAL,['error'=>'联系人手机号已存在']);

        // 验证领域分类ID
        $checkAssortId= AssortRepo::getInstance()->getById($params['assort_id']);
        if (empty($checkAssortId))
            throw new BusinessException(ResponseCode::PARAM_ILLEGAL,['error'=>'领域不存在']);
        if ($checkAssortId->status != 1)
            throw new BusinessException(ResponseCode::PARAM_ILLEGAL,['error'=>'领域不存在']);
    }

    /**
     * 创作者入驻编辑
     * @param MerchantsInfoSaveParams $params
     * @return mixed
     * @throws BusinessException
     * @author shen.zk
     * @date 2023-10-24 18:03
     */
    public function merchantInfoSaveService(MerchantsInfoSaveParams $param)
    {
        $params = $param->toArray();

        $this->baseCheckMerchantInfoParams($params);


        $apply_for_num = $params['apply_for_num'];

        // 验证分账及分账比例
        $is_multipart = 0;
        if (!empty($param->getAccsplitMerNo()) && !empty($param->getMultipartRate()))
        {
            // 验证分账比例是否大于70%
            if ($params['multipart_rate'] > '0.7')
                throw new BusinessException(ResponseCode::PARAM_ILLEGAL,['error'=>'分账比例不得大于70%']);

            $is_multipart = 1;
        }
        $checkStatus = MerchantsInfoApplyForRepo::getInstance()->getByApplyForNum($apply_for_num);
        if (empty($checkStatus))
            throw new BusinessException(ResponseCode::APPLY_FOR_NOT_FUND);
        if ($checkStatus->status == 1)
            throw new BusinessException(ResponseCode::APPLY_FOR_CHECK_FLAG);

        // 上传头像
        $portrait = OssService::getInstance()->saveFile($params['portrait']);

        $data = [
            'user_name'=> $params['user_name'],
            'portrait' => $portrait,
            'contact' => $params['contact'],
            'contact_phone' => $params['contact_phone'],
            'company_int' => $params['company_int'],
            'assort_id' => $params['assort_id'],
            'apply_for_num'=>$params['apply_for_num'],
            'account_no' => $param->getAccsplitMerNo(),
            'status'=>0,
            'update_time'=>date('Y-m-d H:i:s'),
            'is_multipart'=>$is_multipart
        ];
        $result = MerchantsInfoApplyForRepo::getInstance()->save($data,$apply_for_num);
        if (!$result)
            throw new BusinessException(ResponseCode::PARAM_ILLEGAL,['error'=>'入驻申请失败']);

        return $apply_for_num;
    }

    /**
     * 根据申请流水号获取审核信息
     * @return array
     * @throws BusinessException
     * @author shen.zk
     * @date 2023-10-24 18:32
     */
    public function getApplyForInfoService()
    {

        $apply_for_num = request('apply_for_num');
        if (empty($apply_for_num))
            throw new BusinessException(ResponseCode::PARAM_ILLEGAL,['error'=>'入驻申请流水号不能为空']);
        $data = MerchantsInfoApplyForRepo::getInstance()->getByApplyForNum($apply_for_num);
        if (empty($data))
            throw new BusinessException(ResponseCode::APPLY_FOR_NOT_FUND);

        return [
            'status'=>$data->status,
            'content'=>$data->content,
            'mid'    =>$data->apply_for_mid,
        ];
    }
}
